#include <webx/menu.h>
#include <dbentity/T_XG_USER.h>
#include <dbentity/T_XG_NOTE.h>
#include <dbentity/T_XG_CODE.h>
#include <dbentity/T_XG_DBETC.h>
#include <dbentity/T_XG_PARAM.h>

class EditUser : public webx::ProcessBase
{
protected:
	int process();
};

HTTP_WEBAPP(EditUser)

int EditUser::process()
{
	param_string(flag);
	param_string(user);
	param_string(name);

	webx::CheckFileName(user, 0);
	webx::CheckFileName(name, 0);

	auto GetDataId = [](sp<DBConnect> dbconn){
		string dbid;
		string sqlcmd = "SELECT ID FROM T_XG_DBETC WHERE ENABLED>1 ORDER BY STRESS ASC LIMIT 1";

		if (dbconn->select(dbid, sqlcmd) < 0) stdx::Throw(XG_SYSERR, "system error");

		return dbid;
	};
	
	auto UpdateDataStress = [](sp<DBConnect> dbconn, const string& dbid){
		if (dbid.length() > 0) dbconn->execute("UPDATE T_XG_DBETC SET STRESS=STRESS+STEP WHERE ID=?", dbid);
	};

	param_string(mail);
	param_string(code);
	param_string(passwd);

	stdx::tolower(mail);
	stdx::tolower(code);

	int res = 0;
	string sqlcmd;
	CT_XG_USER tab;
	sp<DBConnect> dbconn = webx::GetDBConnect();

	tab.init(dbconn);

	if (flag == "R")
	{
		checkSession();

		if (user.empty() || mail.empty() || code.empty() || passwd.empty() || mail.find('@') == string::npos) return simpleResponse(XG_PARAMERR);

		if (mail != session->get("MAIL")) return simpleResponse(XG_DATAERR);

		if (code != session->get("CODE")) return simpleResponse(XG_AUTHFAIL);

		string dbid = GetDataId(dbconn);

		if (dbid.empty()) return simpleResponse(XG_SYSERR);

		if (name.empty()) name = mail.substr(0, mail.find('@'));

		tab.dbid = dbid;
		tab.user = user;
		tab.name = name;
		tab.mail = mail;
		tab.passwd = passwd;

		tab.level = "0";
		tab.enabled = "1";
		tab.language = "CN";
		tab.grouplist = "normal";
		tab.statetime.update();
		
		if ((res = tab.insert()) < 0) return simpleResponse(res);

		LogTrace(eIMP, "create user[" + user + "] success");

		session->set("GROUPLIST", tab.grouplist.val());
		session->set("LANGUAGE", tab.language.val());
		session->set("DBID", tab.dbid.val());
		session->set("USER", tab.user.val());
		session->set("NAME", tab.name.val());

		UpdateDataStress(dbconn, dbid);
		webx::InitNewUser(user);
	}
	else if (flag == "P")
	{
		checkSession();

		if (passwd.empty()) return simpleResponse(XG_PARAMERR);

		if (code != session->get("CODE") || mail != session->get("MAIL")) checkSystemRight();

		tab.passwd = passwd;
		
		stdx::format(sqlcmd, "MAIL='%s'", mail.c_str());

		res = tab.update(sqlcmd);
	}
	else
	{
		checkLogin();

		if (user.empty()) return simpleResponse(XG_PARAMERR);

		tab.user = user;

		if (flag == "A" || flag == "U")
		{
			string dbid;

			param_string(icon);
			param_string(mail);
			param_string(cert);
			param_string(addr);
			param_string(lang);
			param_string(phone);
			param_string(group);
			param_string(passwd);
			param_string(remark);
			param_string(enabled);

			stdx::tolower(mail);

			if (flag == "A")
			{
				if (name.empty() || mail.empty()) return simpleResponse(XG_PARAMERR);

				checkSystemRight();

				if (lang.empty()) lang = "CN";
				if (group.empty()) group = "normal";
				if (enabled.empty()) enabled = "0";

				if (tab.find() && tab.next()) return simpleResponse(XG_DUPLICATE);

				dbid = GetDataId(dbconn);

				tab.statetime.update();
				tab.level = 0;		
			}
			else
			{
				try
				{
					checkSystemRight();

					mail.clear();
				}
				catch(Exception e)
				{
					if (user != this->user) return simpleResponse(XG_AUTHFAIL);

					if (user == "system") return simpleResponse(XG_AUTHFAIL);
	
					dbid.clear();
					mail.clear();
					lang.clear();
					group.clear();
					remark.clear();
					enabled.clear();
				}
			}

			tab.phone = phone;
			tab.address = addr;

			if (dbid.length() > 0) tab.dbid = dbid;
			if (name.length() > 0) tab.name = name;
			if (mail.length() > 0) tab.mail = mail;
			if (cert.length() > 0) tab.certno = cert;
			if (lang.length() > 0) tab.language = lang;
			if (group.length() > 0) tab.grouplist = group;
			if (passwd.length() > 0) tab.passwd = passwd;
			if (remark.length() > 0) tab.remark = remark;
			if (enabled.length() > 0) tab.enabled = enabled;

			res = flag == "A" ? tab.insert() : tab.update();
			
			if (res < 0) return simpleResponse(res);
			
			if (user == this->user)
			{
				if (group.length() > 0) session->set("GROUPLIST", group);
				if (lang.length() > 0) session->set("LANGUAGE", lang);
				if (name.length() > 0) session->set("NAME", name);
			}

			if (flag == "A")
			{
				UpdateDataStress(dbconn, dbid);
				webx::InitNewUser(user);
			}

			if (icon.length() > 0 && icon.find('?') == string::npos)
			{
				string src = app->getPath() + icon;

				if (path::type(src) == eFILE)
				{
					string extname = stdx::tolower(path::extname(src));
					static set<string> extset = {"png", "jpg", "ico", "bmp", "gif", "jpeg"};

					if (extset.find(extname) == extset.end())
					{
						LogTrace(eERR, "picture format[%s] error", extname.c_str());
					}
					else
					{
						string dest = app->getPath() + stdx::format("pub/usr/pic/%03d/", MD5GetUINT32(user.c_str(), user.length()) % 1000);

						path::mkdir(dest);

						dest += user + ".";

						for (const string& extname : extset) path::remove(dest + extname);

						dest += extname;
		
						CgiMapData item = app->getCgiMapData(icon);

						if (item.url.empty())
						{
							path::rename(src, dest);
						}
						else
						{
							if (CgiMapData::GetKey(icon) != "res/img/user/user.png")
							{
								XFile file;

								if (file.open(dest, eCREATE))
								{
									SmartBuffer content;

									if (app->getFileContent(item.url, content) > 0)
									{
										file.write(content.str(), content.size());
									}
								}
							}
						}
					}
				}
			}
		}
		else if (flag == "D")
		{
			if (user == "system") return simpleResponse(XG_AUTHFAIL);

			checkSystemRight();

			res = tab.remove();
		}
		else
		{
			res = XG_PARAMERR;
		}
	}

	json["code"] = res;
	out << json;
	
	return XG_OK;
}